
import aima.search.framework.Successor;
import aima.search.framework.SuccessorFunction;
import java.util.ArrayList;
import java.util.List;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Marc
 */
public class CarsSuccessorFunction implements SuccessorFunction{

    public List getSuccessors(Object state) {
        ArrayList retval = new ArrayList();
        State CarsState = (State) state;
        CarsHeuristicFunction HF = new CarsHeuristicFunction();
        int Ndrivers = CarsState.getNDrivers();
        for (int i = 0; i < Ndrivers; ++i) {
            for (int j = 0; j < Ndrivers; ++j) {
                if (j != i) {
                    Driver driver1 = CarsState.getDriver(i);
                    int[] aux = driver1.getIdTravellers();
                    for (int k = 0; k < aux.length; ++k) {
                        State newState = new State(CarsState);
                        newState.move(newState.getDriver(i), newState.getDriver(j), aux[k]);
                        retval.add(new Successor(State.MOVE, newState));
                    }
                }
            }
        }
        for (int i = 0; i < Ndrivers; ++i) {
            Driver d = CarsState.getDriver(i);
            int[] travellers = d.getIdTravellers();
            for (int j = 0; j < travellers.length; ++j) {
                State newState1 = new State(CarsState);
                boolean op = newState1.swapTravellers(newState1.getDriver(i), travellers[j], true);
                if (op)retval.add(new Successor(State.SWAP, newState1));
                State newState2 = new State(CarsState);
                op = newState2.swapTravellers(newState2.getDriver(i), travellers[j], false);
                if (op)retval.add(new Successor(State.SWAP, newState2));
            }
        }
       for (int i = 0; i < Ndrivers; ++i) {
            if (CarsState.getDriver(i).getNTravellers() == 0) {
                for (int j = 0; j < Ndrivers; ++j) {
                    if(i != j) {
                        State newState= new State(CarsState);
                        boolean op = newState.deleteDriver(i, j);
                        if (op)retval.add(new Successor(State.DELETE, newState));
                    }
                }
            }
        }
        /*for (int i = 0; i < Ndrivers; ++i) {
            if (CarsState.getDriver(i).getNTravellers() == 0) {
                for (int j = 0; j < Ndrivers; ++j) {
                    if(i != j) {
                        State newState= new State(CarsState);
                        boolean op = newState.deleteDriverWithTravellers(i, j);
                        if (op)retval.add(new Successor(State.DELETE2, newState));
                    }
                }
            }
        }*/
        int[] avaliableDrivers = CarsState.getAvaliableDrivers();
        for (int i = 0; i < avaliableDrivers.length; ++i) {
            State newState = new State(CarsState);
            boolean op = newState.addDriver(avaliableDrivers[i]);
            if (op)retval.add(new Successor(State.ADD, newState));
        }
        /*for (int i = 0; i < Ndrivers; ++i) {
            Driver aux = CarsState.getDriver(i);
            int[] travellers = aux.getIdTravellers();
            for (int j = 0; j < travellers.length - 1; ++j) {
                for (int k = j + 1; k < travellers.length; ++k) {
                    State newState = new State(CarsState);
                    if (newState.swapInCar(aux, travellers[j], travellers[k]));
                        retval.add(new Successor(State.SWAPCAR, newState));
                }
            }
        }*/
        return retval;
    }
}
